package com.nali.dal.statement.function;

import java.text.NumberFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class FunctionBuilder {
	private static Pattern funPattern = Pattern.compile("([\\w_\\$\\.]+)(?:\\((.*)?\\))?");
	private static Pattern commaSplitter = Pattern.compile("\\s*,\\s*");
	public static void main(String[] args) {
		Matcher matcher = funPattern.matcher("abc()");
		matcher.matches();
		System.out.println(matcher.group(2));
		matcher = funPattern.matcher("abc(1,3)");
		matcher.matches();
		System.out.println(matcher.group(2));
		matcher = funPattern.matcher("abc");
		matcher.matches();
		System.out.println(matcher.group(2));
	}
	/**
	 * @return 不能识别抛IllegalArgumentException
	 */
	public static Function complie(String input) {
		//TODO escape
		Matcher matcher = funPattern.matcher(input);
		if(matcher.matches()) {
			String name = matcher.group(1);
			String argString = matcher.group(2);
			if(argString==null) {
				return Function.notFunction(parseArg(name));
			}
			argString=argString.trim();
			List<FunctionArgument> argList;
			if("".equals(argString)) {
				argList = Collections.emptyList();
			} else {
				String[] args = commaSplitter.split(argString);
				argList = new ArrayList<FunctionArgument>(args.length);
				for (int i = 0; i < args.length; i++) {
					argList.add(parseArg(args[i]));
				}
			}
			return Function.function(name, argList);
		} else {
			throw new IllegalArgumentException("not supported syntax:" + input);
		}
	}

	private static FunctionArgument parseArg(String input) {
		if(input.charAt(0)=='\'') {
			if(input.charAt(input.length()-1)!='\'') {
				throw new IllegalArgumentException("startswith \' but not endswith it:" + input);
			}
			return FunctionArgument.value(input.substring(1, input.length()-1));
		} else if(input.equals("?")) {
			return null;
		} else {
			try {
				return FunctionArgument.value(NumberFormat.getInstance().parse(input));//TODO NumberFormat usage
			} catch (ParseException e) {
				Matcher matcher = funPattern.matcher(input);
				if(matcher.matches()) {
					if(matcher.group(2)==null) {
						 if(input.equals("true")) {
							return FunctionArgument.value(true);
						} else if(input.equals("false")) {
							return FunctionArgument.value(false);
						} else if(input.equals("null")) {
							return FunctionArgument.value(null);
						} else {
							return FunctionArgument.column(input);
						}
					}
				}
				throw new IllegalArgumentException("not a number:" + e);
			}
		}
	}

}
